/*
 * Copyright (c) 2016 VUI(https://git.oschina.net/durcframework/vui) All rights reserved.
 */

;(function(){

/**
 * 树控件<br>
 * <pre>
tree = new VUI.Tree({
	renderId:'tree'
	,data:treeData
	,onSelect :function(item) {
		console.log('onSelect text:' + item.text);
	}
});
 * </pre>
 * @class VUI.Tree
 * @extends VUI.Component
 */
VUI.Class('Tree',{
	// 默认属性
	OPTS:{
		/**
		 * @cfg {String} url 请求数据URL
		 */
		url:''
		/**
		 * @cfg {String} method 请求方式
		 */
		,method:'POST'
		/**
		 * @cfg {Boolean} clickToggle 点击节点展开/关闭
		 */
		,clickToggle:false
		/**
		 * @cfg {Boolean} initLoad 创建后立即加载数据
		 */
		,initLoad:true
		/**
		 * @cfg {Function} renderer 节点名称渲染方法,参数item
		 */
		,renderer:function(item) {return item.text;}
	}
	// ----- 事件注释 -----
	
	/**
	 * @event onBeforeExpand 在节点展开之前触发，返回false可以取消展开操作。
	 * @param {Object} e e.item 节点数据
	 */
	
	/**
	 * @event onExpand 在节点展开之后触发。
	 * @param {Object} e e.item 节点数据
	 */
	
	/**
	 * @event onBeforeCollapse 在节点收缩之前触发，返回false可以取消展开操作。
	 * @param {Object} e e.item 节点数据
	 */
	
	/**
	 * @event onCollapse 在节点收缩之后触发。
	 * @param {Object} e e.item 节点数据
	 */
	
	/**
	 * @event onClick 在点击节点时触发。
	 * @param {Object} e e.item 节点数据
	 */
	
	/**
	 * @event onBeforeSelect 在用户选择一个节点之前触发，返回false可以取消选择动作。
	 * @param {Object} e e.item 节点数据
	 */
	
	/**
	 * @event onSelect 在用户选择一个节点候触发。
	 * @param {Object} e e.item 节点数据
	 */
	
	/**
	 * 构造函数
	 * @constructor
	 * @ignore
	 */
	,init:function(opts) {
		this._super(opts);
	}
	/**
	 * 清除选择
	 */
	,clearSelected:function() {
		this.view.clearSelected();
	}
	,controller:function(data) {
		data.rootData = {children:[]};
		if(this.opt('initLoad')) {
			this.postData();
		}
	}
	/**
	 * @ignore
	 */
	,getViewClass:function() {
		return VUI.TreeView;
	}
	/**
	 * 获取选择节点并返回它，如果未选择则返回null。
	 */
	,getSelected:function() {
		return this.view.selectedItem;
	}
	/**
	 * 展开全部
	 */
	,expandAll:function() {
		var items = this.opt('data');
		this.doExpandAll(items);
	}
	/**
	 * 收缩全部
	 */
	,collapseAll:function() {
		var items = this.opt('data');
		this.doCollapseAll(items);
	}
	/**
	 * @private
	 */
	,doExpandAll:function(items) {
		for(var i=0, len=items.length;i<len; i++) {
			var item = items[i];
			this.view.expand(item);
			this.doExpandAll(item.children || []);
		}
	}
	/**
	 * @private
	 */
	,doCollapseAll:function(items) {
		for(var i=0, len=items.length;i<len; i++) {
			var item = items[i];
			this.view.collapse(item);
			this.doCollapseAll(item.children || []);
		}
	}
	/**
	 * 加载数据
	 * @param {Array} data
	 */
	,loadData:function(data) {
		this._formatData(data);
		data = this.loadFilter(data);
		this.opt('data',data);
		this.vueData.rootData.children = data;
	}
	,_formatData:function(data) {
		for(var i=0, len=data.length;i<len; i++) {
			this._formatItem(data[i]);
		}
	}
	,_formatItem:function(item) {
		if(item.state != 'closed') {
			item.state = 'open';
		}
		var children = item.children || [];
		for(var i=0, len=children.length;i<len; i++) {
			this._formatData(children[i]);
		}
	}
	/**
	 * 定义如何从远程服务器加载数据。返回false可以忽略本操作。该函数具备以下参数：<br>
		param：发送到远程服务器的参数对象。<br>
		success(data)：当检索数据成功的时候调用的回调函数。<br>
		error()：当检索数据失败的时候调用的回调函数。<br>
	 */
	,loader:function(param,success,error) {
		var that = this;
		$.ajax({
			type: this.opt('method'),
			url: this.opt('url'),
			traditional:true,
			dataType: 'json',
			data:param,
			success: function(data, textStatus, jqXHR){
				that.fire('LoadSuccess',data);
	        	success(data);
			},
			error:function(XMLHttpRequest, textStatus, errorThrown){
				error && error.call(that,XMLHttpRequest, textStatus, errorThrown)
				that.fire('LoadError',XMLHttpRequest, textStatus, errorThrown);
			}
		});
	}
	/**
	 * 返回过滤过的数据进行展示。返回数据是标准树格式。
	 * @param {Object} data
	 */
	,loadFilter:function(data) {
		return data;
	}
	/**
	 * 远程加载数据
	 * @param {Object} param 请求参数
	 */
	,load:function(param) {
		this.postData(param);
	}
	/**
	 * 重新请求数据,保留之前的查询参数
	 */
	,reload:function() {
		this.postData(this.schData);
	}
	/**
	 * @private
	 */
	,postData:function(param) {
		if(this.opt('url')) {
			param = param || {};
			this.schData = param;
			var that = this;
			var ret = this.fire('BeforeLoad',param);
			if(ret === false) {
				return;
			}
			this.loader(param,function(data){
				that.loadData(data);
			});
		}else{
			this.loadData(this.opt('data'));
		}
	}
	/**
	 * @private
	 */
	,toggle:function(item) {
		this.view.vToggle(item);
	}
	/**
	 * 是否有子节点
	 * @param {Object} 节点数据
	 */
	,hasChild:function(item) {
		return item.children && item.children.length > 0;
	}
	/**
	 * 是否关闭
	 * @param {Object} 节点数据
	 */
	,isClosed:function(item) {
		return this.hasChild(item) && item.state && item.state == 'closed' ;
	}
	/**
	 * 是否开启
	 * @param {Object} 节点数据
	 */
	,isOpen:function(item) {
		var r =  this.hasChild(item) && !this.isClosed(item) ;
		if(r) {
			item.state = 'open';
		}
		return r;
	}
	/**
	 * 是否叶子节点,即下面无子节点
	 * @param {Object} 节点数据
	 */
	,isLeaf:function(item) {
		return !this.hasChild(item);
	}
	/**
	 * 返回节点状态
	 * @param {Object} 节点数据
	 * @return 如果是叶子节点返回'leaf',如果关闭返回'closed',如果打开返回'open'
	 */
	,getState:function(item) {
		if(this.isLeaf(item)) {
			return 'leaf';
		}
		
		if(this.isOpen(item)) {
			return 'open';
		}else if(this.isClosed(item)) {
			return 'closed';
		}
	}
},VUI.Component);

})();